﻿#region Copyright information
// 
// Copyright © 2005-2013 Yongkee Cho. All rights reserved.
// 
// This code is a part of the Biological Object Library and governed under the terms of the
// GNU Lesser General  Public License (LGPL) version 2.1 which accompanies this distribution.
// For more information on the LGPL, please visit http://bol.codeplex.com/license.
// 
// - Filename: DifferencialExpression.cs
// - Author: Yongkee Cho
// - Email: yongkeecho@gmail.com
// - Date Created: 2012-09-06 11:39 AM
// - Last Modified: 2013-01-25 3:59 PM
// 
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using BOL.Linq.Descriptive;

namespace BOL.Linq.Microarray
{
    public static class DifferencialExpression
    {
        /// <summary>
        /// Returns fold change (ratio) of differencial expression (Tusher et al. 2001).
        /// </summary>
        /// <param name="first">Raw expression levels of a gene in control.</param>
        /// <param name="second">Raw expression levels of a gene in treatment.</param>
        /// <returns>Fold change</returns>
        public static decimal FoldChangeRatio(this IEnumerable<decimal> first, IEnumerable<decimal> second)
        {
            return first.Average() / second.Average();
        }

        /// <summary>
        /// Returns fold change (ratio) of differencial expression (Tusher et al. 2001).
        /// </summary>
        /// <param name="first">Raw expression levels of a gene in control.</param>
        /// <param name="second">Raw expression levels of a gene in treatment.</param>
        /// <returns>Fold change</returns>
        public static double FoldChangeRatio(this IEnumerable<double> first, IEnumerable<double> second)
        {
            return first.Average() / second.Average();
        }

        /// <summary>
        /// Returns fold change (ratio) of differencial expression (Tusher et al. 2001).
        /// </summary>
        /// <param name="first">Raw expression levels of a gene in control.</param>
        /// <param name="second">Raw expression levels of a gene in treatment.</param>
        /// <returns>Fold change</returns>
        public static float FoldChangeRatio(this IEnumerable<float> first, IEnumerable<float> second)
        {
            return first.Average() / second.Average();
        }

        /// <summary>
        /// Returns fold change (difference) of differencial expression (Guo et al. 2006 and Choe et al. 2005).
        /// </summary>
        /// <param name="first">Log2 expression levels of a gene in control.</param>
        /// <param name="second">Log2 expression levels of a gene in treatment.</param>
        /// <returns>Fold change</returns>
        public static decimal FoldChangeDifference(this IEnumerable<decimal> first, IEnumerable<decimal> second)
        {
            return first.Average() - second.Average();
        }

        /// <summary>
        /// Returns fold change (difference) of differencial expression (Guo et al. 2006 and Choe et al. 2005).
        /// </summary>
        /// <param name="first">Log2 expression levels of a gene in control.</param>
        /// <param name="second">Log2 expression levels of a gene in treatment.</param>
        /// <returns>Fold change</returns>
        public static double FoldChangeDifference(this IEnumerable<double> first, IEnumerable<double> second)
        {
            return first.Average() - second.Average();
        }

        /// <summary>
        /// Returns fold change (difference) of differencial expression (Guo et al. 2006 and Choe et al. 2005).
        /// </summary>
        /// <param name="first">Log2 expression levels of a gene in control.</param>
        /// <param name="second">Log2 expression levels of a gene in treatment.</param>
        /// <returns>Fold change</returns>
        public static float FoldChangeDifference(this IEnumerable<float> first, IEnumerable<float> second)
        {
            return first.Average() - second.Average();
        }

        /// <summary>
        /// Returns T-statistics of differencial expression (Tusher et al. 2001).
        /// </summary>
        /// <param name="first">Log2 expression levels of a gene in control.</param>
        /// <param name="second">Log2 expression levels of a gene in treatment.</param>
        /// <returns>Fold change</returns>
        public static decimal T(this IEnumerable<decimal> first, IEnumerable<decimal> second)
        {
            var x = first.ToList();
            var y = second.ToList();

            return (x.Average() - y.Average()) / x.Concat(y).StandardDeviation();
        }

        /// <summary>
        /// Returns T-statistics of differencial expression (Tusher et al. 2001).
        /// </summary>
        /// <param name="first">Log2 expression levels of a gene in control.</param>
        /// <param name="second">Log2 expression levels of a gene in treatment.</param>
        /// <returns>Fold change</returns>
        public static double T(this IEnumerable<double> first, IEnumerable<double> second)
        {
            var x = first.ToList();
            var y = second.ToList();

            return (x.Average() - y.Average()) / x.Concat(y).StandardDeviation();
        }

        /// <summary>
        /// Returns T-statistics of differencial expression (Tusher et al. 2001).
        /// </summary>
        /// <param name="first">Log2 expression levels of a gene in control.</param>
        /// <param name="second">Log2 expression levels of a gene in treatment.</param>
        /// <returns>Fold change</returns>
        public static float T(this IEnumerable<float> first, IEnumerable<float> second)
        {
            var x = first.ToList();
            var y = second.ToList();

            return (x.Average() - y.Average()) / x.Concat(y).StandardDeviation();
        }

        /// <summary>
        /// Returns SAM T-statistics of differencial expression (Tusher et al. 2001).
        /// </summary>
        /// <param name="first">Log2 expression levels of a gene in control.</param>
        /// <param name="second">Log2 expression levels of a gene in treatment.</param>
        /// <param name="s0">Constant chosen to minimize the coefficient of variation.</param>
        /// <returns>Fold change</returns>
        public static decimal SamT(this IEnumerable<decimal> first, IEnumerable<decimal> second, decimal s0)
        {
            var x = first.ToList();
            var y = second.ToList();

            return (x.Average() - y.Average()) / (x.Concat(y).StandardDeviation() + s0);
        }

        /// <summary>
        /// Returns SAM T-statistics of differencial expression (Tusher et al. 2001).
        /// </summary>
        /// <param name="first">Log2 expression levels of a gene in control.</param>
        /// <param name="second">Log2 expression levels of a gene in treatment.</param>
        /// <param name="s0">Constant chosen to minimize the coefficient of variation.</param>
        /// <returns>Fold change</returns>
        public static double SamT(this IEnumerable<double> first, IEnumerable<double> second, double s0)
        {
            var x = first.ToList();
            var y = second.ToList();

            return (x.Average() - y.Average()) / (x.Concat(y).StandardDeviation() + s0);
        }

        /// <summary>
        /// Returns SAM T-statistics of differencial expression (Tusher et al. 2001).
        /// </summary>
        /// <param name="first">Log2 expression levels of a gene in control.</param>
        /// <param name="second">Log2 expression levels of a gene in treatment.</param>
        /// <param name="s0">Constant chosen to minimize the coefficient of variation.</param>
        /// <returns>Fold change</returns>
        public static float SamT(this IEnumerable<float> first, IEnumerable<float> second, float s0)
        {
            var x = first.ToList();
            var y = second.ToList();

            return (x.Average() - y.Average()) / (x.Concat(y).StandardDeviation() + s0);
        }
    }
}
